package com.ryskoo.catering.coupon.service;

import com.ryskoo.catering.coupon.domain.CouponPO;
import com.ryskoo.catering.coupon.repository.ICouponRepository;
import com.ryskoo.catering.coupondetail.domain.CouponDetailPO;
import com.ryskoo.catering.coupondetail.service.ICouponDetailService;
import com.ryskoo.catering.productmain.domain.ProductMainPO;
import com.ryskoo.catering.productmain.service.IProductMainService;
import com.ryskoo.framework.core.bean.QueryConditionEnum;
import com.ryskoo.framework.core.bean.QueryMessageDTO;
import com.ryskoo.framework.core.exception.InvalidParamException;
import com.ryskoo.framework.core.service.BasicServiceImpl;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class CouponServiceImpl extends BasicServiceImpl<CouponPO> implements ICouponService{
    @Autowired
    private ICouponRepository couponRepository;

    @Autowired
    private IProductMainService productMainService;

    @PostConstruct
    public void init() {
        this.setDao(couponRepository);
    }
    @Autowired
    private ICouponDetailService couponDetailService;

    /**
     * 根据商户uuid获取店铺类优惠券集合，且在有效期内
     *
     * @param vendorUuid
     * @return
     */
    @Override
    public List<CouponPO> getListForVendorByVendorUuid(String vendorUuid) {
        List<CouponPO> list = couponRepository.getListForVendorByVendorUuid(vendorUuid);
        return list;
    }


    /**
     * 根据商户uuid获取店铺类优惠券集合,且根据会员uuid判断该优惠券是否可领取
     *
     * @param vendorUuid
     * @param customerUuid
     * @return
     */
    @Override
    public List<CouponPO> getListForVendorByVendorAndCustomer(String vendorUuid, String customerUuid) {
    	//获取店铺发布的有效优惠券列表
        List<CouponPO> list = this.getListForVendorByVendorUuid(vendorUuid);
        List<CouponPO> validCoupons = new ArrayList<CouponPO>();

        Map<String, List<CouponDetailPO>> detailsMap = null;
        if(CollectionUtils.isNotEmpty(list)){
            List<String> couponUuids = list.stream().map(CouponPO::getUuid).collect(Collectors.toList());
            //获取优惠券明细
            List<CouponDetailPO> detailPOList = couponDetailService.getListByCustomerUuidAndCouponUuids(customerUuid, couponUuids);
            if(CollectionUtils.isNotEmpty(detailPOList)){
                //根据couponUuid进行分组
                detailsMap = detailPOList.stream().collect(Collectors.groupingBy(CouponDetailPO::getCouponUuid));
            }
            for(CouponPO coupon : list){
            	//已经领取完的不需要在前台显示
            	if (coupon.getGenerateNum() >= coupon.getTotalNum()) {
            		continue;
            	}
            	
            	 //优惠券领取的数量
            	 List<CouponDetailPO> details = detailsMap.get(coupon.getUuid());
            	 
                //已经被领取的数量
                int num = details.size();
                
                //如果该优惠券设置了限领数量，并且达到限领数量，则不让领取
                if(coupon.getLimitNum() > 0 && num >= coupon.getLimitNum()){
                    coupon.setReceive(false);
                }
                
            	validCoupons.add(coupon);
            }
        }
        return validCoupons;
    }

    /**
     * 领取优惠券
     *
     * @param couponUuid
     * @param customerUuid
     */
    @Override
    public void receive(String couponUuid, String customerUuid) {
        CouponPO coupon = this.getByUuid(couponUuid);
        if(null == coupon){
            throw new InvalidParamException("优惠券不存在");
        }
        if(coupon.getGenerateNum() >= coupon.getTotalNum()){
            throw new InvalidParamException("已领完");
        }
        List<CouponDetailPO> detailPOList = couponDetailService.getListByCustomerUuidAndCouponUuid(customerUuid, couponUuid);
        if(CollectionUtils.isEmpty(detailPOList)){
            //领取优惠券
            couponDetailService.receive(coupon, customerUuid);
            coupon.setGenerateNum(coupon.getGenerateNum() + 1);
        }else{
        	//如果优惠券设置了限领数量，并且该会员领取的数量超过限领，则不让再领取
        	if (coupon.getLimitNum() > 0 && detailPOList.size() >= coupon.getLimitNum()) {
        		throw new InvalidParamException("每人限领" + coupon.getLimitNum() + "张");
        	} else {
        		 //领取优惠券
                couponDetailService.receive(coupon, customerUuid);
                coupon.setGenerateNum(coupon.getGenerateNum() + 1);
        	}
        }
        this.update(coupon);
    }


	@Override
	public List<CouponPO> queryListAndProductByCondition(QueryMessageDTO qm) {
		List<CouponPO> list = this.queryByConditionAndPage(qm);
		if(CollectionUtils.isNotEmpty(list)){
			List<String> productUuids = list.stream().filter(CouponPO->StringUtils.isNotEmpty(CouponPO.getProductUuid())).map(CouponPO::getProductUuid).collect(Collectors.toList());
			if(CollectionUtils.isNotEmpty(productUuids)){
				// 根据productUuids获取ProductMain
				QueryMessageDTO productQm = new QueryMessageDTO();
				productQm.addCondition("uuid", QueryConditionEnum.IN.name(), productUuids);
				List<ProductMainPO> productList = productMainService.getProductInfoFromES(productQm);
				if(CollectionUtils.isNotEmpty(productList)){
					// 设置map
					Map<String,String> productMap = new HashMap<String,String>();
					productList.stream().forEach(ProductMainPO -> productMap.put(ProductMainPO.getUuid(), ProductMainPO.getName()));
					list.stream().forEach(CouponPO -> CouponPO.setProductName(productMap.get(CouponPO.getProductUuid())));
				}
			}
		}
		return list;
	}

    @Override
    public void sendCouponsToMembers(String[] memberUuidArr, String[] couponUuidArr) {
        for (String memberUuid:memberUuidArr) {
            for (String couponUuid:couponUuidArr) {
                CouponPO coupon = this.getByUuid(couponUuid);
                if(null == coupon){
                    throw new InvalidParamException("优惠券不存在");
                }
                couponDetailService.receive(coupon, memberUuid);
            }
        }
    }
}
